#include "juzhen.h"
#include "ui_juzhen.h"
#include <QMessageBox>
#include <QTableWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QStringList>
#include <QVector>
#include <QInputDialog>
#include <QTextEdit>
#include <QString>
#include<cmath>
using namespace std;
juzhen::juzhen(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::juzhen)
{
    ui->setupUi(this);
}

juzhen::~juzhen()
{
    delete ui;
}
void juzhen::on_spinBox_matrix_row_1_valueChanged(int arg1)
{
    //设置矩阵1的行数
    ui->tableWidget_matrix_1->setRowCount(arg1); 
}


void juzhen::on_spinBox_matrix_column_1_valueChanged(int arg1)
{
    //设置矩阵1的列数
    ui->tableWidget_matrix_1->setColumnCount(arg1);
}

//创建矩阵1
void juzhen::on_create_matrix_1_clicked()
{
    //获取矩阵1行数列数的值
    int row = ui->spinBox_matrix_row_1->value();
    int col = ui->spinBox_matrix_column_1->value();

    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < col; ++j) {
            //初始值设为0
            ui->tableWidget_matrix_1->setItem(i, j, new QTableWidgetItem("0"));
        }
    }
}
void juzhen::on_tableWidget_matrix_1_cellChanged(int row, int column)
{

}
//同理，以下为矩阵2的
void juzhen::on_spinBox_matrix_row_2_valueChanged(int arg1)
{
    ui->tableWidget_matrix_2->setRowCount(arg1);
}


void juzhen::on_spinBox_matrix_column_2_valueChanged(int arg1)
{
    ui->tableWidget_matrix_2->setColumnCount(arg1);
}


void juzhen::on_create_matrix_2_clicked()
{
    int row = ui->spinBox_matrix_row_2->value();
    int col = ui->spinBox_matrix_column_2->value();

    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < col; ++j) {
            ui->tableWidget_matrix_2->setItem(i, j, new QTableWidgetItem("0"));
        }
    }
}
void juzhen::on_tableWidget_matrix_2_cellChanged(int row, int column)
{

}
void juzhen::on_tableWidget_matrix_answer_cellChanged(int row, int column)
{

}
//矩阵乘法
void juzhen::on_multiply_button_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();
    int row2 = ui->spinBox_matrix_row_2->value();
    int col2 = ui->spinBox_matrix_column_2->value();
    //检查矩阵是否可以相乘
    if (col1 != row2) {
        QMessageBox::warning(this, "错误", "矩阵相乘，矩阵1的列数必须=矩阵2的行数");
        return;
    }

    QVector<QVector<double>> matrix1;
    QVector<QVector<double>> matrix2;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }

    for (int i = 0; i < row2; ++i) {
        QVector<double> row;
        for (int j = 0; j < col2; ++j) {
            row.append(ui->tableWidget_matrix_2->item(i, j)->text().toDouble());
        }
        matrix2.append(row);
    }

    QVector<QVector<double>> result(row1, QVector<double>(col2, 0));

    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col2; ++j) {
            for (int k = 0; k < col1; ++k) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }
    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col2);
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col2; ++j) {
            ui->tableWidget_matrix_answer->setItem(i, j, new QTableWidgetItem(QString::number(result[i][j])));
        }
    }
}
//加法
void juzhen::on_add_button_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();
    int row2 = ui->spinBox_matrix_row_2->value();
    int col2 = ui->spinBox_matrix_column_2->value();
    if (row1 != row2||col1!=col2) {
        QMessageBox::warning(this, "错误", "同型矩阵才能相加");
        return;
    }

    QVector<QVector<double>> matrix1;
    QVector<QVector<double>> matrix2;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }

    for (int i = 0; i < row2; ++i) {
        QVector<double> row;
        for (int j = 0; j < col2; ++j) {
            row.append(ui->tableWidget_matrix_2->item(i, j)->text().toDouble());
        }
        matrix2.append(row);
    }

    QVector<QVector<double>> result(row1, QVector<double>(col2, 0));

    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col2; ++j) {
                result[i][j] = matrix1[i][j] + matrix2[i][j];
        }
    }
    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col2);
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col2; ++j) {
            ui->tableWidget_matrix_answer->setItem(i, j, new QTableWidgetItem(QString::number(result[i][j])));
        }
    }
}
//减法
void juzhen::on_subtrac_button_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();
    int row2 = ui->spinBox_matrix_row_2->value();
    int col2 = ui->spinBox_matrix_column_2->value();
    if (row1 != row2||col1!=col2) {
        QMessageBox::warning(this, "错误", "同型矩阵才能相减");
        return;
    }

    QVector<QVector<double>> matrix1;
    QVector<QVector<double>> matrix2;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }

    for (int i = 0; i < row2; ++i) {
        QVector<double> row;
        for (int j = 0; j < col2; ++j) {
            row.append(ui->tableWidget_matrix_2->item(i, j)->text().toDouble());
        }
        matrix2.append(row);
    }

    QVector<QVector<double>> result(row1, QVector<double>(col2, 0));

    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col2; ++j) {
            result[i][j] = matrix1[i][j] - matrix2[i][j];
        }
    }
    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col2);
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col2; ++j) {
            ui->tableWidget_matrix_answer->setItem(i, j, new QTableWidgetItem(QString::number(result[i][j])));
        }
    }
}
//行列式
double juzhen::calculateDeterminant(const QVector<QVector<double>>& matrix)
{
    int n = matrix.size();
    if (n == 1) {
        return matrix[0][0];
    }
    else if (n == 2) {
        return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
    }
    else {
        //对于大于2的矩阵，递归
        //用拉普拉斯定理，按行展开（下面按第一行展开）
        double determinant = 0;
        //遍历矩阵的第一行每一个a0j（第一行i=0）
        for (int j = 0; j < n; ++j) {
            //创建个子矩阵，用于递归计算
            QVector<QVector<double>> subMatrix;
            //遍历原矩阵的剩余行（跳过第一行）
            for (int i = 1; i < n; ++i) {
                //创建个行向量，存储子矩阵的当前行
                QVector<double> row;
                for (int k = 0; k < n; ++k) {
                    //跳过与a0j在同一列的元素
                    if (k == j) continue;
                    row.append(matrix[i][k]);
                }
                subMatrix.append(row);
            }
            //计算当前元素a0j的代数余子式（即子矩阵的行列式）的符号和乘积
            //因为是按第一行展开，但第一行是从i=0,j=0开始,所以如果j是偶数，则使用正号，否则使用负号
            determinant += (j % 2 == 0 ? 1 : -1) * matrix[0][j] * calculateDeterminant(subMatrix);
        }
        return determinant;
    }
}
void juzhen::on_Determinant_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();
    if (row1 != col1) {
        QMessageBox::warning(this, "错误", "只有方阵才有行列式");
        return;
    }

    QVector<QVector<double>> matrix1;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }
    double determinant = calculateDeterminant(matrix1);
    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col1);
    ui->tableWidget_matrix_answer->setItem(0, 0, new QTableWidgetItem(QString::number(determinant)));
}
//伴随矩阵
void juzhen::on_adjoint_matrix_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();
    if (row1 != col1) {
        QMessageBox::warning(this, "错误", "只有方阵才有伴随矩阵");
        return;
    }

    QVector<QVector<double>> matrix1;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }

    QVector<QVector<double>> adjointMatrix(row1, QVector<double>(col1, 0));
     //遍历matrix1的每一个元素，计算其代数余子式并填入伴随矩阵
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col1; ++j) {
            //创建一个tempMatrix作为matrix1的副本，用于计算代数余子式
            QVector<QVector<double>> tempMatrix = matrix1;
            //从tempMatrix中移除第i行和第j列
            removeRow(tempMatrix,i);
            removeColumn(tempMatrix,j);
            //计算代数余子式的行列式值
            double determinant = 0;
            //如果tempMatrix只剩下一个元素，则行列式就是该元素
            if (tempMatrix.size() == 1) {
                determinant = tempMatrix[0][0];
            }
            else {
                determinant = calculateDeterminant(tempMatrix);
            }
            //将代数余子式乘以(-1)^(i+j)填入最终结果的伴随矩阵
            adjointMatrix[j][i] = (i + j) % 2 == 0 ? determinant : -determinant;
        }
    }
    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col1);
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col1; ++j) {
            ui->tableWidget_matrix_answer->setItem(i, j, new QTableWidgetItem(QString::number(adjointMatrix[i][j])));
        }
    }
}
void juzhen::removeRow(QVector<QVector<double>>& matrix, int rowIndex) {
    if (rowIndex < 0 || rowIndex >= matrix.size()) {
        return;
    }
    matrix.removeAt(rowIndex);
}
void juzhen::removeColumn(QVector<QVector<double>>& matrix, int columnIndex) {
    for (QVector<double>& row : matrix) {
        if (columnIndex < 0 || columnIndex >= row.size()) {
            continue;
        }
        row.removeAt(columnIndex);
    }
}
//逆矩阵
void juzhen::on_inverse_matrix_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();
    if (row1 != col1) {
        QMessageBox::warning(this, "错误", "只有方阵才有逆矩阵");
        return;
    }

    QVector<QVector<double>> matrix1;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }
    //如果行列式为0，则此矩阵没有逆矩阵
    double determinant = calculateDeterminant(matrix1);
    if (determinant == 0) {
        QMessageBox::warning(this, "错误", "矩阵没有逆矩阵");
        return;
    }

    QVector<QVector<double>> adjointMatrix(row1, QVector<double>(col1, 0));
    //我这里用的A逆=A伴随/A的行列式（因为前面有了求伴随矩阵和行列式的逻辑，比较好写）
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col1; ++j) {
            QVector<QVector<double>> tempMatrix = matrix1;
            removeRow(tempMatrix,i);
            removeColumn(tempMatrix,j);
            double determinant = 0;
            if (tempMatrix.size() == 1) {
                determinant = tempMatrix[0][0];
            } else {
                determinant = calculateDeterminant(tempMatrix);
            }
            adjointMatrix[j][i] = (i + j) % 2 == 0 ? determinant : -determinant;
        }
    }

    QVector<QVector<double>> inverseMatrix(row1, QVector<double>(col1, 0));
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col1; ++j) {
            inverseMatrix[i][j] = adjointMatrix[i][j] / determinant;
        }
    }

    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col1);
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col1; ++j) {
            ui->tableWidget_matrix_answer->setItem(i, j, new QTableWidgetItem(QString::number(inverseMatrix[i][j])));
        }
    }
}
//行最简型矩阵，用高斯消元法（要用到交换两行和倍加操作）
//交换矩阵中两行
void swapRows(QVector<QVector<double>>& matrix, int row1, int row2) {
    QVector<double> temp = matrix[row1];
    matrix[row1] = matrix[row2];
    matrix[row2] = temp;
}

//将矩阵的某一行乘以一个系数并加到另一行上
void addRowMultipliedBy(QVector<QVector<double>>& matrix, int destRow, double factor, int srcRow) {
    for (int j = 0; j < matrix[0].size(); ++j) {
        matrix[destRow][j] += factor * matrix[srcRow][j];
    }
}
void juzhen::on_row_minimalist_matrix_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();

    QVector<QVector<double>> matrix1;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }
    for (int pivotCol = 0; pivotCol < col1; ++pivotCol) {
        //寻找当前列中的非零元素作为主元
        int pivotRow = -1;
        for (int i = pivotCol; i < row1; ++i) {
            if (fabs(matrix1[i][pivotCol]) > 1e-10) { // 使用小阈值来避免除以零
                pivotRow = i;
                break;
            }
        }
        //该列所有元素都是零，无需进一步操作
        if (pivotRow == -1) {
            continue;
        }

        //如果主元不在当前列顶部，则交换行，将主元行移到当前列顶部
        if (pivotRow != pivotCol) {
            swapRows(matrix1, pivotRow, pivotCol);
        }

        // 将主元变为1
        double pivotValue = matrix1[pivotCol][pivotCol];
        for (int j = pivotCol; j < col1; ++j) {
            matrix1[pivotCol][j] /= pivotValue;
        }

        //消除其他行的主元列元素
        for (int i = 0; i < row1; ++i) {
            if (i != pivotCol) {
                double factor = matrix1[i][pivotCol];
                addRowMultipliedBy(matrix1, i, -factor, pivotCol);
            }
        }

        //将主元列下方的元素变为0
        for (int i = pivotCol + 1; i < row1; ++i) {
            for (int j = pivotCol + 1; j < col1; ++j) {
                if (j != i) {
                    double factor = matrix1[i][j] / matrix1[j][j];
                    addRowMultipliedBy(matrix1, i, -factor, j);
                }
            }
        }
    }
    ui->tableWidget_matrix_answer->setRowCount(row1);
    ui->tableWidget_matrix_answer->setColumnCount(col1);
    for (int i = 0; i < row1; ++i) {
        for (int j = 0; j < col1; ++j) {
            ui->tableWidget_matrix_answer->setItem(i, j, new QTableWidgetItem(QString::number(matrix1[i][j])));
        }
    }
}
//矩阵的秩
void juzhen::on_the_rank_of_matrix_clicked()
{
    int row1 = ui->spinBox_matrix_row_1->value();
    int col1 = ui->spinBox_matrix_column_1->value();

    QVector<QVector<double>> matrix1;

    for (int i = 0; i < row1; ++i) {
        QVector<double> row;
        for (int j = 0; j < col1; ++j) {
            row.append(ui->tableWidget_matrix_1->item(i, j)->text().toDouble());
        }
        matrix1.append(row);
    }
    for (int pivotCol = 0; pivotCol < col1; ++pivotCol) {
        //寻找当前列中的非零元素作为主元
        int pivotRow = -1;
        for (int i = pivotCol; i < row1; ++i) {
            if (fabs(matrix1[i][pivotCol]) > 1e-10) { // 使用小阈值来避免除以零
                pivotRow = i;
                break;
            }
        }
        //该列所有元素都是零，无需进一步操作
        if (pivotRow == -1) {
            continue;
        }

        //如果主元不在当前列顶部，则交换行，将主元行移到当前列顶部
        if (pivotRow != pivotCol) {
            swapRows(matrix1, pivotRow, pivotCol);
        }

        // 将主元变为1
        double pivotValue = matrix1[pivotCol][pivotCol];
        for (int j = pivotCol; j < col1; ++j) {
            matrix1[pivotCol][j] /= pivotValue;
        }

        //消除其他行的主元列元素
        for (int i = 0; i < row1; ++i) {
            if (i != pivotCol) {
                double factor = matrix1[i][pivotCol];
                addRowMultipliedBy(matrix1, i, -factor, pivotCol);
            }
        }

        //将主元列下方的元素变为0
        for (int i = pivotCol + 1; i < row1; ++i) {
            for (int j = pivotCol + 1; j < col1; ++j) {
                if (j != i) {
                    double factor = matrix1[i][j] / matrix1[j][j];
                    addRowMultipliedBy(matrix1, i, -factor, j);
                }
            }
        }
    }
    int rank = 0;
    for (int i = 0; i < row1; ++i) {
        bool allZero = true;
        for (int j = 0; j < col1; ++j) {
            if (std::fabs(matrix1[i][j]) > 1e-10) {
                allZero = false;
                break;
            }
        }
        if (!allZero) {
            ++rank;
        }
    }

    ui->tableWidget_matrix_answer->setRowCount(1);
    ui->tableWidget_matrix_answer->setColumnCount(1);
    ui->tableWidget_matrix_answer->setItem(0, 0, new QTableWidgetItem(QString::number(rank)));
}
